package com.telenav.snowsweeper.renderer;

import java.util.Vector;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Cap;

import com.telenav.snowsweeper.data.Edge;
import com.telenav.snowsweeper.data.EdgeMap;
import com.telenav.snowsweeper.data.Point;
import com.telenav.snowsweeper.data.Route;
import com.telenav.snowsweeper.framework.ui.IObjectRenderer;
import com.telenav.snowsweeper.util.DisplayUtil;

public class RouteRenderer implements IObjectRenderer {

	MapEdgeRenderer.RendererParams edgeParams;
	RendererParams params = new RendererParams();
	long lastUpdateTimeStamp = -1;
	
	private EdgeMap edgeMap;
	private Paint p;
	
	public RouteRenderer(EdgeMap edgeMap, MapEdgeRenderer.RendererParams edgeParams) {
		this.edgeMap = edgeMap;
		this.edgeParams = edgeParams;
		
		p = new Paint();
		p.setStyle(Paint.Style.STROKE);
		p.setStrokeCap(Cap.ROUND);
	}
	
	private Vector<Point> renderPoints = new Vector<Point>();
	private Vector<Edge> renderEdges = new Vector<Edge>();
	@Override
	public void render(Canvas canvas, Layer layer) {
		if (layer == Layer.Route) {
			try {
				params.copyRendererData(renderPoints, renderEdges);
				
				p.setColor(DisplayUtil.COLOR_ROUTE);
				if (renderPoints.size() >= 2) {
					int width = Util.mapDist2Screen(DisplayUtil.ROUTE_WIDTH, edgeParams.scaleX);
					width = Util.getValue(width, DisplayUtil.ROUTE_MAX_WIDTH_PX, DisplayUtil.ROUTE_MIN_WIDTH_PX);
					p.setStrokeWidth(width);
					
					Point first = renderPoints.elementAt(0);
					Point second;
					int[] head, tail;
					for (int i = 1; i < renderPoints.size(); ++i) {
						second = renderPoints.elementAt(i);
						head = first.getScreenXY(edgeParams.timeStamp);
						tail = second.getScreenXY(edgeParams.timeStamp);
						canvas.drawLine(head[0], head[1], tail[0], tail[1], p);
						first = second;
					}
				}
				
				if (renderEdges.size() > 0) {
					int width = Util.mapDist2Screen(DisplayUtil.HINT_WIDTH, edgeParams.scaleX);
					width = Util.getValue(width, DisplayUtil.HINT_MAX_WIDTH_PX, DisplayUtil.HINT_MIN_WIDTH_PX);
					p.setStrokeWidth(width);
					p.setColor(DisplayUtil.COLOR_HINT);
					int[] head, tail;
					for (Edge e : renderEdges) {
						head = e.getBegin().getScreenXY(edgeParams.timeStamp);
						tail = e.getEnd().getScreenXY(edgeParams.timeStamp);
						canvas.drawLine(head[0], head[1], tail[0], tail[1], p);
					}
				}
			}
			catch (Exception e) {
				e.printStackTrace();
			}
			finally {
				renderEdges.clear();
				renderPoints.clear();
			}
		}
	}

	@Override
	public void build(long timeStamp) {
		
	}
	
	public RendererParams getParams() {
		return params;
	}
	
	public class RendererParams {
		Route route = new Route();
		Vector<Edge> edges = new Vector<Edge>();
		
		public synchronized String getRouteString() {
			return route.toRequestParamers(edgeMap);
		}
		
		public synchronized int getRoutePointSize() {
			return route.getPointSize();
		}
		
		public synchronized void addPoint(Point point) {
			route.addPoint(point);
		}
		
		public synchronized void clearRoute() {
			route.clear();
		}
		
        public synchronized void setRoute(Route route)
        {
            this.route = route;
        }
        
		public synchronized void copyRendererData(Vector<Point> out_points, Vector<Edge> out_edges) {
			out_points.addAll(route.getPoints());
			out_edges.addAll(edges);
		}
		
		public synchronized void addHint(Vector<Edge> edges) {
			this.edges.clear();
			this.edges.addAll(edges);
		}
		
		public synchronized void clearHint() {
			edges.clear();
		}
	}
}
